--- /dev/null
+Subject: Increase x86 interrupt vector range
+
+Remove the limit of 256 interrupt vectors by changing the value
+stored in orig_{e,r}ax to be the negated interrupt vector.
+The orig_{e,r}ax needs to be < 0 to allow the signal code to
+distinguish between return from interrupt and return from syscall.
+With this change applied, NR_IRQS can be > 256.
+
+Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
+---
+ arch/i386/kernel/entry.S | 4 ++--
+ arch/i386/kernel/irq.c | 4 ++--
+ arch/x86_64/kernel/entry.S | 2 +-
+ arch/x86_64/kernel/irq.c | 4 ++--
+ arch/x86_64/kernel/smp.c | 4 ++--
+ include/asm-x86_64/hw_irq.h | 2 +-
+ 6 files changed, 10 insertions(+), 10 deletions(-)
+
+diff -r 7d239c83edea arch/i386/kernel/entry.S
+--- a/arch/i386/kernel/entry.S Mon Mar 20 06:00:20 2006 +0000
++++ b/arch/i386/kernel/entry.S Fri Mar 31 17:01:35 2006 +0100
+@@ -406,7 +406,7 @@ ENTRY(irq_entries_start)
+ ENTRY(irq_entries_start)
+ .rept NR_IRQS
+ ALIGN
+-1: pushl $vector-256
++1: pushl $~(vector)
+ jmp common_interrupt
+ .data
+ .long 1b
+@@ -423,7 +423,7 @@ common_interrupt:
+
+ #define BUILD_INTERRUPT(name, nr) \
+ ENTRY(name) \
+- pushl $nr-256; \
++ pushl $~(nr); \
+ SAVE_ALL \
+ movl %esp,%eax; \
+ call smp_/**/name; \
+diff -r 7d239c83edea arch/i386/kernel/irq.c
+--- a/arch/i386/kernel/irq.c Mon Mar 20 06:00:20 2006 +0000
++++ b/arch/i386/kernel/irq.c Fri Mar 31 17:01:35 2006 +0100
+@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPU
+ */
+ fastcall unsigned int do_IRQ(struct pt_regs *regs)
+ {
+- /* high bits used in ret_from_ code */
+- int irq = regs->orig_eax & 0xff;
++ /* high bit used in ret_from_ code */
++ int irq = ~regs->orig_eax;
+ #ifdef CONFIG_4KSTACKS
+ union irq_ctx *curctx, *irqctx;
+ u32 *isp;
+diff -r 7d239c83edea arch/x86_64/kernel/entry.S
+--- a/arch/x86_64/kernel/entry.S Mon Mar 20 06:00:20 2006 +0000
++++ b/arch/x86_64/kernel/entry.S Fri Mar 31 17:01:35 2006 +0100
+@@ -609,7 +609,7 @@ retint_kernel:
+ */
+ .macro apicinterrupt num,func
+ INTR_FRAME
+- pushq $\num-256
++ pushq $~(\num)
+ CFI_ADJUST_CFA_OFFSET 8
+ interrupt \func
+ jmp ret_from_intr
+diff -r 7d239c83edea arch/x86_64/kernel/irq.c
+--- a/arch/x86_64/kernel/irq.c Mon Mar 20 06:00:20 2006 +0000
++++ b/arch/x86_64/kernel/irq.c Fri Mar 31 17:01:35 2006 +0100
+@@ -96,8 +96,8 @@ skip:
+ */
+ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
+ {
+- /* high bits used in ret_from_ code */
+- unsigned irq = regs->orig_rax & 0xff;
++ /* high bit used in ret_from_ code */
++ unsigned irq = ~regs->orig_rax;
+
+ exit_idle();
+ irq_enter();
+diff -r 7d239c83edea arch/x86_64/kernel/smp.c
+--- a/arch/x86_64/kernel/smp.c Mon Mar 20 06:00:20 2006 +0000
++++ b/arch/x86_64/kernel/smp.c Fri Mar 31 17:01:35 2006 +0100
+@@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt
+
+ cpu = smp_processor_id();
+ /*
+- * orig_rax contains the interrupt vector - 256.
++ * orig_rax contains the negated interrupt vector.
+ * Use that to determine where the sender put the data.
+ */
+- sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START;
++ sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
+ f = &per_cpu(flush_state, sender);
+
+ if (!cpu_isset(cpu, f->flush_cpumask))
+diff -r 7d239c83edea include/asm-x86_64/hw_irq.h
+--- a/include/asm-x86_64/hw_irq.h Mon Mar 20 06:00:20 2006 +0000
++++ b/include/asm-x86_64/hw_irq.h Fri Mar 31 17:01:35 2006 +0100
+@@ -127,7 +127,7 @@ __asm__( \
+ __asm__( \
+ "\n.p2align\n" \
+ "IRQ" #nr "_interrupt:\n\t" \
+- "push $" #nr "-256 ; " \
++ "push $~(" #nr ") ; " \
+ "jmp common_interrupt");
+
+ #if defined(CONFIG_X86_IO_APIC)